/**
 * 下载Node.js二进制文件
 * 用于确保自动化服务可以在没有Node环境的计算机上运行
 */

const fs = require('fs-extra');
const path = require('path');
const https = require('https');
const { createWriteStream } = require('fs');
const { spawn } = require('child_process');
const os = require('os');

// 项目根目录
const rootDir = path.resolve(__dirname, '..');
// 下载目标目录
const targetDir = path.join(rootDir, 'resources', 'node');

// 根据系统选择不同版本的Node.js
function getNodeDownloadUrl() {
  const nodeVersion = 'v20.12.0'; // 与项目兼容的Node.js版本
  let platform = '';
  let arch = '';
  let ext = '';

  // 获取平台信息
  switch (process.platform) {
    case 'win32':
      platform = 'win';
      ext = 'zip';
      break;
    case 'darwin':
      platform = 'darwin';
      ext = 'tar.gz';
      break;
    case 'linux':
      platform = 'linux';
      ext = 'tar.gz';
      break;
    default:
      throw new Error(`不支持的平台: ${process.platform}`);
  }

  // 获取架构信息
  switch (process.arch) {
    case 'x64':
      arch = 'x64';
      break;
    case 'arm64':
      arch = 'arm64';
      break;
    default:
      throw new Error(`不支持的架构: ${process.arch}`);
  }

  // 特殊情况处理
  if (platform === 'win') {
    return `https://nodejs.org/dist/${nodeVersion}/node-${nodeVersion}-${platform}-${arch}.${ext}`;
  }

  return `https://nodejs.org/dist/${nodeVersion}/node-${nodeVersion}-${platform}-${arch}.${ext}`;
}

// 下载文件
function downloadFile(url, destPath) {
  return new Promise((resolve, reject) => {
    console.log(`下载: ${url}`);
    console.log(`保存到: ${destPath}`);

    const file = createWriteStream(destPath);

    https.get(url, (response) => {
      if (response.statusCode !== 200) {
        reject(new Error(`下载失败，状态码: ${response.statusCode}`));
        return;
      }

      response.pipe(file);

      file.on('finish', () => {
        file.close();
        resolve();
      });
    }).on('error', (err) => {
      fs.unlink(destPath, () => {}); // 删除未完成的文件
      reject(err);
    });
  });
}

// 解压文件
async function extractFile(filePath, targetDir) {
  console.log(`解压 ${filePath} 到 ${targetDir}`);

  if (filePath.endsWith('.zip')) {
    // Windows平台使用unzip命令或解压库
    if (process.platform === 'win32') {
      // 使用PowerShell解压
      return new Promise((resolve, reject) => {
        const ps = spawn('powershell', [
          '-command',
          `& {Expand-Archive -Path "${filePath}" -DestinationPath "${targetDir}" -Force}`
        ]);

        ps.on('close', (code) => {
          if (code === 0) {
            resolve();
          } else {
            reject(new Error(`解压失败，退出码: ${code}`));
          }
        });

        ps.stderr.on('data', (data) => {
          console.error(`解压错误: ${data}`);
        });
      });
    }
  } else if (filePath.endsWith('.tar.gz')) {
    // Unix平台使用tar命令
    return new Promise((resolve, reject) => {
      const tar = spawn('tar', ['-xzf', filePath, '-C', targetDir]);

      tar.on('close', (code) => {
        if (code === 0) {
          resolve();
        } else {
          reject(new Error(`解压失败，退出码: ${code}`));
        }
      });

      tar.stderr.on('data', (data) => {
        console.error(`解压错误: ${data}`);
      });
    });
  } else {
    throw new Error(`不支持的文件格式: ${filePath}`);
  }
}

// 复制主要的Node可执行文件到根目录
function copyNodeExecutable(extractedDir, targetDir) {
  console.log('正在复制Node.js可执行文件...');

  // 根据平台确定源目录和文件名
  let nodeBinaryName = process.platform === 'win32' ? 'node.exe' : 'node';
  let binarySourcePath = '';

  // 查找解压后的目录
  const files = fs.readdirSync(extractedDir);
  const nodeDir = files.find(file => file.startsWith('node-'));

  if (!nodeDir) {
    throw new Error('找不到Node.js目录');
  }

  const fullNodeDir = path.join(extractedDir, nodeDir);

  // 根据平台查找二进制文件
  if (process.platform === 'win32') {
    binarySourcePath = path.join(fullNodeDir, nodeBinaryName);
  } else {
    binarySourcePath = path.join(fullNodeDir, 'bin', nodeBinaryName);
  }

  // 确保目标目录存在
  fs.ensureDirSync(targetDir);

  // 复制可执行文件
  fs.copyFileSync(binarySourcePath, path.join(targetDir, nodeBinaryName));
  console.log(`已复制 ${nodeBinaryName} 到 ${targetDir}`);

  // 设置可执行权限（在Unix平台上）
  if (process.platform !== 'win32') {
    fs.chmodSync(path.join(targetDir, nodeBinaryName), '755');
    console.log('已设置可执行权限');
  }
}

// 主函数
async function main() {
  try {
    // 创建临时目录
    const tempDir = path.join(os.tmpdir(), 'node-download-' + Date.now());
    fs.ensureDirSync(tempDir);
    console.log(`创建临时目录: ${tempDir}`);

    // 确保目标目录存在
    fs.ensureDirSync(targetDir);

    // 获取下载URL
    const downloadUrl = getNodeDownloadUrl();
    const fileName = path.basename(downloadUrl);
    const filePath = path.join(tempDir, fileName);

    // 下载Node.js
    await downloadFile(downloadUrl, filePath);

    // 解压文件
    await extractFile(filePath, tempDir);

    // 复制可执行文件
    copyNodeExecutable(tempDir, targetDir);

    // 清理临时文件
    console.log('清理临时文件...');
    fs.removeSync(tempDir);

    console.log('✅ Node.js二进制文件已成功准备好');
  } catch (error) {
    console.error('❌ 下载Node.js失败:', error);
    process.exit(1);
  }
}

// 运行主函数
main();